﻿using UnityEngine;
using System.Collections;
#if UNITY_EDITOR
using UnityEditor;
#endif
using System.Collections.Generic;
using System;

using Game.AIBehaviorTree;
using System.Linq;
using System.IO;


enum ClickEventType{
    createTree = 0,
    loadTree,
    unloadTree,
    deleteTree,
    pasteNodeInsert,
    pasteNodeAdd,
    copyNode,
    cutNode,

}

[Serializable]
public class BTNodeWorkView : BTViewBase
{

    #region Public Variables

    #endregion

    #region Protected Variables
    Vector2 mousePos;
    int deleteNodeId = -1;
    //点击右键时鼠标所在node
    BTNodeBase selectedNode = null;
    //要添加的节点类型
    string nodeType = null;



    //滚动条
    private Vector2 mScrollPosition = Vector2.zero;
    public Vector2 offsetScroll
    {
        get{
            return mScrollPosition;
        }
    }

    /// <summary>
    /// 纯node类名
    /// </summary>
    Type[] nodeTypes;
    /// <summary>
    /// 带 类型/类名
    /// </summary>
    static String[] nodeTypeNames;
    static int numMenuTag = 10;
    #endregion

    #region Constructors
    public BTNodeWorkView() : base("Work View") { }
    #endregion

    #region Main Methods
    public override void UpdateView(Rect editorRect, Rect precentageRect,Event e,BTNodeGraph curGraph)
    {
        base.UpdateView(editorRect,precentageRect,e, curGraph);

        mScrollPosition = GUI.BeginScrollView(viewRect, mScrollPosition,
                    maxViewRect, true, true);

        GUI.Box(maxViewRect, viewTitle,viewSkin.GetStyle("ViewBG"));

        //Draw Grid
        BTNodeUtils.DrawGrid(maxViewRect, 60f, 0.15f, Color.white);
        BTNodeUtils.DrawGrid(maxViewRect, 20f, 0.05f, Color.white);

        GUILayout.BeginArea(maxViewRect);
        if(curGraph != null)
        {
            curGraph.UpdateGraphGUI(e, maxViewRect, viewSkin);
        }

        GUILayout.EndArea();
        GUI.EndScrollView();
        ProcessEvents(e);
    }

    public override void ProcessEvents(Event e)
    {
        base.ProcessEvents(e);
        
        //鼠标是否在这个view的区域内
        if (viewRect.Contains(e.mousePosition))
        {
            //左键
            if(e.button == 0 && e.isMouse)
            {
                
                if(e.type == EventType.mouseDown)
                {
                    
                }

                if (e.type == EventType.MouseDrag)
                {
                }
                if (e.type == EventType.MouseUp)
                {
                }
            }
            //右键
            if (e.button == 1)
            {
                if (e.type == EventType.mouseDown)
                {
                    this.mousePos = e.mousePosition;
                    //点击的是否是node，是node弹出不同菜单
                    bool overNode = false;
                    deleteNodeId = -1;
                    selectedNode = null;
                    if(curGraph != null)
                    {
                        if(curGraph.nodes.Count > 0)
                        {
                            for(int i = 0; i < curGraph.nodes.Count; i ++)
                            {
                                Rect rect = curGraph.nodes[i].nodeRect;
                                rect.x -= this.offsetScroll.x;
                                rect.y -= this.offsetScroll.y;
                                if (rect.Contains(mousePos))
                                {
                                    deleteNodeId = i;
                                    selectedNode = curGraph.nodes[i];
                                    overNode = true;
                                }
                            }
                        }
                    }
                    if(!overNode)
                    {
                        ProcessContextMenu(e, 0);
                    }
                    else
                    {
                        ProcessContextMenu(e, 1);
                    }
                    
                }

              
            }

        }

    }


    #endregion

    #region Utility Methods

    /// <summary>
    /// 获取所有node列表
    /// </summary>
    void CreateTypeLists()
    {
        // get list of possible node types
        // i.e., all types that extend TreeNode and are not abstract
        nodeTypes = typeof(BNode).Assembly.GetTypes()
                .Where(type => type.IsSubclassOf(typeof(BNode)) && !type.IsAbstract).ToArray<Type>();
        nodeTypeNames = Array.ConvertAll<Type, String>(nodeTypes,
            new Converter<Type, String>(
                delegate (Type type)
                {
                    if (type.IsSubclassOf(typeof(BNodeDecorator)))
                    {
                        return "Decorators/" + type.Name;
                    }
                    else if (type.IsSubclassOf(typeof(BNodeComposite)))
                    {
                        return "Compositors/" + type.Name;
                    }
                    else if (type.IsSubclassOf(typeof(BNodeCondition)))
                    {
                        return "Conditions/" + type.Name;
                    }
                    else
                    {
                        return "Leaves/" + type.Name;
                    }
                }));
    }

    /// <summary>
    /// 右键点击回调,弹出菜单
    /// </summary>
    /// <param name="e"></param>
    /// <param name="contextId"></param>
    private void ProcessContextMenu(Event e,int contextId)
    {
        CreateTypeLists();

        GenericMenu menu = new GenericMenu();
        //0为点击view背景，1为点击node
        if(contextId == 0)
        {
            menu.AddItem(new GUIContent("Create Graph"), false, ContextCallback, ClickEventType.createTree);
            menu.AddItem(new GUIContent("Load Graph"), false, ContextCallback, ClickEventType.loadTree);

            if (curGraph != null)
            {
                menu.AddSeparator("");
                menu.AddItem(new GUIContent("Unload Graph"), false, ContextCallback, ClickEventType.unloadTree);

                menu.AddSeparator("");
                if(curGraph.rootNode == null)
                {
                    string strNodeMenu;
                    for (int i = 0; i < nodeTypeNames.Length; i++)
                    {
                        strNodeMenu = "Add Root/" + nodeTypeNames[i];
                        menu.AddItem(new GUIContent(strNodeMenu), false, ContextCallback, (i + numMenuTag).ToString());
                    }
                }
                

              //  menu.AddItem(new GUIContent("Add Node/111"), false, ContextCallback, "3");
                // menu.AddItem(new GUIContent("Add node"), false, ContextCallback, "4");
            }
        }
        //点击在某个note上
        else if(contextId == 1)
        {
            menu.AddItem(new GUIContent("Delete Node"), false, ContextCallback, ClickEventType.deleteTree);
            //  menu.AddItem(new GUIContent("Load Graph"), false, ContextCallback, "6");
            bool isCopy = true;
            if(BTreeEditorData.instance.hasCopyNode(out isCopy))
            {
              menu.AddItem(new GUIContent("Paste Before theNode"), false, ContextCallback, ClickEventType.pasteNodeInsert);
              menu.AddItem(new GUIContent("Paste add at theNode"), false, ContextCallback, ClickEventType.pasteNodeAdd);
            }
            
             menu.AddItem(new GUIContent("Copy Node"), false, ContextCallback, ClickEventType.copyNode);
             menu.AddItem(new GUIContent("Cut Node"), false, ContextCallback, ClickEventType.cutNode);

            menu.AddSeparator("");
            if (curGraph.rootNode != null)
            {
                string strNodeMenu;
                for (int i = 0; i < nodeTypeNames.Length; i++)
                {
                    strNodeMenu = "Add Node/" + nodeTypeNames[i];
                    menu.AddItem(new GUIContent(strNodeMenu), false, ContextCallback, (i + numMenuTag));
                }
            }
        }
       
        menu.ShowAsContext();
        e.Use();

    }

    private void ContextCallback(object obj)
    {
        //int str = (int)obj;
        int str = Convert.ToInt16(obj);
        //int valueE = int.Parse(obj.ToString());
       // Debug.Log(obj.ToString());
        switch(str)
        {
            case (int)ClickEventType.createTree:
                Debug.Log("Create Tree");
                BTNodePopupWindow.InitNodePopup();
                break;

            case (int)ClickEventType.loadTree:
                Debug.Log("Load Tree");
                BTNLoadTreePopWindow.InitNodePopup();
                break;

            case (int)ClickEventType.unloadTree:
                Debug.Log("Unload Tree");
                BTNodeUtils.UnloadGraph();
                break;

            case (int)ClickEventType.deleteTree:
                Debug.Log("Delete node");
                BTNodeUtils.removeNode(selectedNode,curGraph);
                //BTNodeUtils.DeleteNode(deleteNodeId,curGraph);
                break;

                case (int)ClickEventType.pasteNodeInsert:
                Debug.Log("pasteNodeInsert");
                BTreeEditorData.instance.pasteBeforeNode(selectedNode);
                break;

                case (int)ClickEventType.pasteNodeAdd:
                Debug.Log("pasteNodeAdd");
                BTreeEditorData.instance.pasteNode(selectedNode);
                break;

                case (int)ClickEventType.copyNode:
                Debug.Log("copyNode");
                BTreeEditorData.instance.copyNode(selectedNode,true);
                break;

                case (int)ClickEventType.cutNode:
                Debug.Log("cutNode");
                BTreeEditorData.instance.copyNode(selectedNode,false);
                break;

            default:
                //添加节点
                BTNodeUtils.CreateNode(curGraph, selectedNode,Path.GetFileName(nodeTypeNames[str - numMenuTag]), this.mousePos);

                break;
        }
    }

    
    #endregion
}
